#! /bin/bash

cmd=$1
ip=$2
NICName=$3

function help() {
    cat <<-EOF
    Description:
        jm9200_openstack --- jm9200 OpenStack config utils
        this installation script is only applicable to kylin-server-v10-sp1 system. 

    Note:
        for all password: The all default value is "123". the passwords of all relevant services and components are set to 123.
        
    Usage:
        ./jm9200_openstack [options]

    options:
        -h      show this help
        -v      show virsion

    commands:
        createAllDB                         create all database and grant their privileges
        createKeystoneDB                    create keystone database and grant it privileges
        createGlanceDB                      create glance database and grant it privileges
        createPlaceme                       create placement database and grant it privileges
        createNovaDB                        create nova database and grant it privileges
        createNeutronDB                     create neutron database and grant it privileges

        removeAllDB                         remove all database
        removeKeystoneDB                    remove keystone database
        removeGlanceDB                      remove glance database
        removePlacementDB                   remove placement database
        removeNovaDB                        remove nova database
        removeNeutronDB                     remove neutron database

        updateSourceAndIPConfig -ip -NIC    update source

        openstackEnvironment                install all oepnstack package
        mysqlAndMemcachedConfig             config of mysql and memcached
        rabbitmqConfig                      config of rabbitmq
        keystoneConfig                      config of keystone
        glanceConfig                        config of glance
        placementConfig                     config of placement
        novaConfig                          config of nova
        neutronConfig                       config of neutron
        dashboardConfig                     config of dashboard 

        oneStepDeployment                   one step deployment of openstack

        restartAllService                   restart all service
        stopAllService                      stop
        enableAllService                    enable all service
        restartAfterReboot                  restart service after reboot
        clearLog                            clear all log of openstack service
        changeNetwork -ip -NIC              change network environment
EOF
    exit 0
}

function version() {
    cat <<-EOF
	jm9200_openstack utils v1.0.0
EOF
    exit 0

}

function removeKeystoneDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE keystone;   
EOF
}

function removeGlanceDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE glance;   
EOF
}

function removePlacementDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE placement;
EOF
}

function removeNovaDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE nova_api;
    DROP DATABASE nova;
    DROP DATABASE nova_cell0;
EOF
}

function removeNeutronDB() {
    mysql -u root -p123 <<EOF
    DROP DATABASE neutron;
EOF
}

function removeAllDB() {
    removeKeystoneDB
    removeGlanceDB
    removePlacementDB
    removeNovaDB
    removeNeutronDB
}

function createKeystoneDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE keystone;
    GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '123';   
EOF
}

function createGlanceDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE glance;
    GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%'  IDENTIFIED BY '123';
EOF
}

function createPlacementDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE placement;
    GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%'  IDENTIFIED BY '123';
EOF
}

function createNovaDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE nova_api;
    CREATE DATABASE nova;
    CREATE DATABASE nova_cell0;
    GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%'  IDENTIFIED BY '123';
EOF
}

function createNeutronDB() {
    mysql -u root -p123 <<EOF
    CREATE DATABASE neutron;
    GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost'  IDENTIFIED BY '123';
    GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%'  IDENTIFIED BY '123';
EOF
}

function createAllDB() {
    createKeystoneDB
    createGlanceDB
    createPlacementDB
    createNovaDB
    createNeutronDB
}

function updateSourceAndIPConfig() {
    /bin/cp -rf ./conf/kylin_aarch64.repo /etc/yum.repos.d/

    sudo sed -i 's/\(GRUB_CMDLINE_LINUX=\).*/\1"quiet splash iommu.passthrough=on kvm.ignore_msrs=1 vfio-pci.ids=0731:9200 "/' /etc/default/grub
    echo 'vfio-pci' >/etc/modules-load.d/vfio-pci.conf
    echo 'vfio-iommu-type1' >/etc/modules-load.d/vfio-iommu.conf
    echo 'options vfio-pci ids=0731:9200' >/etc/modprobe.d/vfio.conf

    if [[ $ip != "" && $NICName != "" ]]; then
        sudo sed -i 's/\(bind-address = \).*/\1'$ip'/' ./conf/openstack.cnf
        sudo sed -i 's/\(my_ip = \).*/\1'$ip'/' ./conf/nova.conf
        sudo sed -i 's/\(local_ip = \).*/\1'$ip'/' ./conf/linuxbridge_agent.ini
        sudo sed -i 's/\(physical_interface_mappings = provider:\).*/\1'$NICName'/' ./conf/linuxbridge_agent.ini
        sudo sed -i '/controller/d' /etc/hosts
        sudo sed -i '$a'$ip'	controller' /etc/hosts
    else
        echo "please input correct host ip and NIC name"
    fi
    /bin/cp -rf ./conf/hostname /etc/

    sudo grub2-mkconfig -o /boot/grub2/grub.cfg

    yum makecache

    yum -y update
    echo 'config success!'
}

function openstackEnvironment() {
    yum -y install python3-openstackclient

    sleep 1

    yum -y install mariadb mariadb-server python3-PyMySQL

    sleep 1

    yum -y install memcached python3-memcached

    sleep 1

    yum -y install rabbitmq-server
    systemctl enable rabbitmq-server.service
    systemctl restart rabbitmq-server.service

    sleep 1

    yum -y install openstack-keystone httpd python3-mod_wsgi

    sleep 1

    yum -y install openstack-glance

    sleep 1

    yum -y install openstack-placement-api

    sleep 1

    yum -y install openstack-nova-api openstack-nova-conductor openstack-nova-novncproxy openstack-nova-scheduler
    yum -y install openstack-nova-compute

    sleep 1

    yum -y install openstack-neutron openstack-neutron-ml2 openstack-neutron-linuxbridge ebtables
    yum -y install openstack-neutron-linuxbridge ebtables ipset

    sleep 1

    yum -y install openstack-dashboard

    sleep 1

    yum -y install virt-manager

    sleep 1

    yum -y install edk2*

    sleep 1

    yum -y install AAVMF
}

function mysqlAndMemcachedConfig() {
    /bin/cp -rf ./conf/openstack.cnf /etc/my.cnf.d/
    /bin/cp -rf ./conf/memcached /etc/sysconfig/

    systemctl enable mariadb.service
    systemctl restart mariadb.service
    systemctl enable memcached.service
    systemctl restart memcached.service

    mysql_secure_installation <<EOF

    y
    123
    123
    y
    n
    y
    y
EOF

    systemctl restart memcached.service
}

function rabbitmqConfig() {
    rabbitmqctl add_user openstack 123
    rabbitmqctl set_permissions openstack ".*" ".*" ".*"
    systemctl restart rabbitmq-server.service
}

function keystoneConfig() {
    /bin/cp -rf ./conf/keystone.conf /etc/keystone/

    su -s /bin/sh -c "keystone-manage db_sync" keystone
    keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
    keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
    keystone-manage bootstrap --bootstrap-password 123 --bootstrap-admin-url http://controller:5000/v3/ --bootstrap-internal-url http://controller:5000/v3/ --bootstrap-public-url http://controller:5000/v3/ --bootstrap-region-id RegionOne

    /bin/cp -rf ./conf/httpd.conf /etc/httpd/conf/
    ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

    systemctl enable httpd.service
    systemctl restart httpd.service

    . admin-openrc
    openstack project create --domain default --description "Service Project" service
    openstack project create --domain default --description "Demo Project" myproject
    openstack user create --domain default --password 123 myuser
    openstack role create myrole
    openstack role add --project myproject --user myuser myrole
}

function glanceConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 glance
    openstack role add --project service --user glance admin
    openstack service create --name glance --description "OpenStack Image" image
    openstack endpoint create --region RegionOne image public http://controller:9292
    openstack endpoint create --region RegionOne image internal http://controller:9292
    openstack endpoint create --region RegionOne image admin http://controller:9292

    /bin/cp -rf ./conf/glance-api.conf /etc/glance/

    su -s /bin/sh -c "glance-manage db_sync" glance
    systemctl enable openstack-glance-api.service
    systemctl restart openstack-glance-api.service

    #glance image-create --name "uos" --file uos.iso --disk-format qcow2 --container-format bare --visibility public
}

function placementConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 placement
    openstack role add --project service --user placement admin
    openstack service create --name placement --description "Placement API" placement
    openstack endpoint create --region RegionOne placement public http://controller:8778
    openstack endpoint create --region RegionOne placement internal http://controller:8778
    openstack endpoint create --region RegionOne placement admin http://controller:8778

    /bin/cp -rf ./conf/placement.conf /etc/placement/
    /bin/cp -rf ./conf/00-placement-api.conf /etc/httpd/conf.d/

    su -s /bin/sh -c "placement-manage db sync" placement
    systemctl restart httpd
}

function novaConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 nova
    openstack role add --project service --user nova admin
    openstack service create --name nova --description "OpenStack Compute" compute
    openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1
    openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1
    openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1

    /bin/cp -rf ./conf/nova.conf /etc/nova/

    su -s /bin/sh -c "nova-manage api_db sync" nova
    su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
    su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova
    su -s /bin/sh -c "nova-manage db sync" nova
    su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova

    systemctl enable openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
    systemctl restart openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service

    systemctl enable libvirtd.service openstack-nova-compute.service
    systemctl restart libvirtd.service openstack-nova-compute.service

    su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
}

function neutronConfig() {
    . admin-openrc
    openstack user create --domain default --password 123 neutron
    openstack role add --project service --user neutron admin
    openstack service create --name neutron --description "OpenStack Networking" network
    openstack endpoint create --region RegionOne network public http://controller:9696
    openstack endpoint create --region RegionOne network internal http://controller:9696
    openstack endpoint create --region RegionOne network admin http://controller:9696

    /bin/cp -rf ./conf/neutron.conf /etc/neutron/
    /bin/cp -rf ./conf/ml2_conf.ini /etc/neutron/plugins/ml2/
    /bin/cp -rf ./conf/linuxbridge_agent.ini /etc/neutron/plugins/ml2/
    /bin/cp -rf ./conf/l3_agent.ini /etc/neutron/
    /bin/cp -rf ./conf/dhcp_agent.ini /etc/neutron/
    /bin/cp -rf ./conf/metadata_agent.ini /etc/neutron/

    ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
    su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf   --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

    systemctl restart openstack-nova-api.service
    systemctl enable neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
    systemctl restart neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
    systemctl enable neutron-l3-agent.service
    systemctl restart neutron-l3-agent.service

    modprobe br_netfilter
    systemctl restart openstack-nova-compute.service
    systemctl enable neutron-linuxbridge-agent.service
    systemctl restart neutron-linuxbridge-agent.service

    systemctl restart neutron-*
}

function dashboardConfig() {
    /bin/cp -rf ./conf/local_settings /etc/openstack-dashboard/
    /bin/cp -rf ./conf/openstack-dashboard.conf /etc/httpd/conf.d/
    /bin/cp -rf ./conf/qemu.conf /etc/libvirt/

    systemctl restart httpd.service memcached.service libvirtd
}

function restartAllService() {
    systemctl restart mariadb.service
    systemctl restart memcached.service
    systemctl restart rabbitmq-server.service
    systemctl restart httpd.service
    systemctl restart openstack-glance-api.service
    systemctl restart openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
    systemctl restart libvirtd.service openstack-nova-compute.service
    systemctl restart openstack-nova-api.service
    systemctl restart neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
    systemctl restart neutron-l3-agent.service

    echo " "
}

function stopAllService() {
    systemctl stop mariadb.service
    systemctl stop memcached.service
    systemctl stop rabbitmq-server.service
    systemctl stop httpd.service
    systemctl stop openstack-glance-api.service
    systemctl stop openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
    systemctl stop libvirtd.service openstack-nova-compute.service
    systemctl stop openstack-nova-api.service
    systemctl stop neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
    systemctl stop neutron-l3-agent.service

    echo " "
}

function enableAllService() {
    systemctl enable mariadb.service
    systemctl enable memcached.service
    systemctl enable rabbitmq-server.service
    systemctl enable httpd.service
    systemctl enable openstack-glance-api.service
    systemctl enable openstack-nova-api.service openstack-nova-scheduler.service openstack-nova-conductor.service openstack-nova-novncproxy.service
    systemctl enable libvirtd.service openstack-nova-compute.service
    systemctl enable neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service
    systemctl enable neutron-l3-agent.service
}

function restartAfterReboot() {
    systemctl restart rabbitmq-server.service
    systemctl restart memcached.service
    #systemctl restart neutron-*

    echo " "
}

function oneStepDeployment() {
    openstackEnvironment
    mysqlAndMemcachedConfig

    createAllDB
    rabbitmqConfig
    keystoneConfig
    glanceConfig
    placementConfig
    novaConfig
    neutronConfig
    dashboardConfig
}

function clearLog() {
    rm /var/log/nova/*
    rm /var/log/neutron/*
    rm /var/log/apache2/*
    rm /var/log/keystone/*
    rm /var/log/placement/*
    rm /var/log/glance/*
}

function changeNetwork() {
    if [[ $ip != "" && $NICName != "" ]]; then
        sudo sed -i 's/\(bind-address = \).*/\1'$ip'/' /etc/my.cnf.d/openstack.cnf
        sudo sed -i 's/\(my_ip = \).*/\1'$ip'/' /etc/nova/nova.conf
        sudo sed -i 's/\(local_ip = \).*/\1'$ip'/' /etc/neutron/plugins/ml2/linuxbridge_agent.ini
        sudo sed -i 's/\(physical_interface_mappings = provider:\).*/\1'$NICName'/' /etc/neutron/plugins/ml2/linuxbridge_agent.ini
        sudo sed -i '/controller/d' /etc/hosts
        sudo sed -i '$a'$ip'	controller' /etc/hosts
    else
        echo "please input correct host ip and NIC name"
    fi

    systemctl restart network
}

# function openstackVMConfig() {
#     folder="/var/lib/nova/instances"
#     for file in ${folder}/*; do
#         if [[ -f ${file}"/disk" && ! -f ${file}"/mark" ]]
#         then
#             sudo touch ${file}"/mark"
#             sudo mv ${file}"/disk" ${file}"/disk.temp"
#             sudo mv ${file}"/disk.eph0" ${file}"/disk"
#             sudo mv ${file}"/disk.temp" ${file}"/disk.eph0"
#         fi
#     done
# }

case $cmd in
-h | --help)
    help
    ;;
-v | --version)
    version
    ;;
createAllDB)
    createAllDB
    ;;
createKeystoneDB)
    createKeystoneDB
    ;;
createGlanceDB)
    createGlanceDB
    ;;
createPlacementDB)
    createPlacementDB
    ;;
createNovaDB)
    createNovaDB
    ;;
createNeutronDB)
    createNeutronDB
    ;;
removeAllDB)
    removeAllDB
    ;;
removeKeystoneDB)
    removeKeystoneDB
    ;;
removeGlanceDB)
    removeGlanceDB
    ;;
removePlacementDB)
    removePlacementDB
    ;;
removeNovaDB)
    removeNovaDB
    ;;
removeNeutronDB)
    removeNeutronDB
    ;;
updateSourceAndIPConfig)
    updateSourceAndIPConfig
    ;;
openstackEnvironment)
    openstackEnvironment
    ;;
mysqlAndMemcachedConfig)
    mysqlAndMemcachedConfig
    ;;
rabbitmqConfig)
    rabbitmqConfig
    ;;
keystoneConfig)
    keystoneConfig
    ;;
glanceConfig)
    glanceConfig
    ;;
placementConfig)
    placementConfig
    ;;
novaConfig)
    novaConfig
    ;;
neutronConfig)
    neutronConfig
    ;;
dashboardConfig)
    dashboardConfig
    ;;
restartAfterReboot)
    restartAfterReboot
    ;;
restartAllService)
    restartAllService
    ;;
stopAllService)
    stopAllService
    ;;
enableAllService)
    enableAllService
    ;;
oneStepDeployment)
    oneStepDeployment
    ;;
clearLog)
    clearLog
    ;;
changeNetwork)
    changeNetwork
    ;;
# openstackVMConfig)
#     openstackVMConfig
#     ;;
*)
    echo "error command $cmd"
    ;;
esac
